using Microsoft.Extensions.Logging;
using System.Security.Cryptography;

namespace SumerCoreDevOps.Infrastructure.Security;

/// <summary>
/// 加密密钥管理器
/// 负责自动生成、加载和管理加密密钥
/// </summary>
public class EncryptionKeyManager
{
    private readonly ILogger<EncryptionKeyManager> _logger;
    private readonly string _keyFilePath;

    public EncryptionKeyManager(ILogger<EncryptionKeyManager> logger, string? customKeyPath = null)
    {
        _logger = logger;

        // 密钥文件路径：优先使用自定义路径，否则使用默认路径
        // 默认路径：<应用数据目录>/SumerCoreDevOps/encryption.key
        if (!string.IsNullOrEmpty(customKeyPath))
        {
            _keyFilePath = customKeyPath;
        }
        else
        {
            var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            var sumerDir = Path.Combine(appDataPath, "SumerCoreDevOps");
            Directory.CreateDirectory(sumerDir);
            _keyFilePath = Path.Combine(sumerDir, "encryption.key");
        }
    }

    /// <summary>
    /// 初始化并获取加密密钥
    /// 优先级：环境变量 > 文件系统 > 自动生成
    /// </summary>
    public string GetOrCreateEncryptionKey()
    {
        // 1. 最高优先级：环境变量（生产环境、容器化部署）
        var envKey = Environment.GetEnvironmentVariable("SUMER_ENCRYPTION_KEY");
        if (!string.IsNullOrEmpty(envKey))
        {
            _logger.LogInformation("使用环境变量中的加密密钥");

            // 验证密钥强度
            if (!ValidateKeyStrength(envKey))
            {
                _logger.LogWarning("⚠️  环境变量中的密钥强度不足，建议至少 32 个字符且包含大小写字母、数字和特殊符号");
            }

            return envKey;
        }

        // 2. 中等优先级：文件系统（开发环境、本地部署）
        if (File.Exists(_keyFilePath))
        {
            try
            {
                var fileKey = File.ReadAllText(_keyFilePath).Trim();
                if (!string.IsNullOrEmpty(fileKey))
                {
                    _logger.LogInformation("从文件加载加密密钥: {Path}", _keyFilePath);
                    return fileKey;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "读取密钥文件失败: {Path}", _keyFilePath);
            }
        }

        // 3. 最低优先级：自动生成（首次启动）
        _logger.LogWarning("⚠️  未找到加密密钥，自动生成新密钥");
        var newKey = GenerateSecureKey();

        // 保存到文件系统
        try
        {
            File.WriteAllText(_keyFilePath, newKey);

            // 设置文件权限（仅所有者可读写）
            if (!OperatingSystem.IsWindows())
            {
                File.SetUnixFileMode(_keyFilePath, UnixFileMode.UserRead | UnixFileMode.UserWrite);
            }

            _logger.LogInformation("✅ 加密密钥已生成并保存到: {Path}", _keyFilePath);
            _logger.LogWarning("📋 开发环境密钥已保存到文件系统");
            _logger.LogWarning("🔐 生产环境请使用环境变量或密钥管理服务配置密钥");
            _logger.LogWarning("💡 设置环境变量: export SUMER_ENCRYPTION_KEY=\"{Key}\"", newKey.Substring(0, 8) + "...");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存密钥文件失败: {Path}", _keyFilePath);
            _logger.LogWarning("密钥已生成但无法持久化，请手动配置环境变量");
        }

        return newKey;
    }

    /// <summary>
    /// 生成安全的加密密钥
    /// 使用 256 位随机数据，Base64 编码
    /// </summary>
    private string GenerateSecureKey()
    {
        // 生成 256 位（32 字节）的随机密钥
        var keyBytes = new byte[32];
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(keyBytes);
        }

        // Base64 编码，结果约 44 个字符
        return Convert.ToBase64String(keyBytes);
    }

    /// <summary>
    /// 验证密钥强度
    /// </summary>
    private bool ValidateKeyStrength(string key)
    {
        if (string.IsNullOrEmpty(key) || key.Length < 32)
        {
            return false;
        }

        var hasUpper = key.Any(char.IsUpper);
        var hasLower = key.Any(char.IsLower);
        var hasDigit = key.Any(char.IsDigit);
        var hasSpecial = key.Any(c => !char.IsLetterOrDigit(c));

        // 至少包含 3 种字符类型
        var typeCount = (hasUpper ? 1 : 0) + (hasLower ? 1 : 0) + (hasDigit ? 1 : 0) + (hasSpecial ? 1 : 0);
        return typeCount >= 3;
    }

    /// <summary>
    /// 获取密钥文件路径（用于显示给用户）
    /// </summary>
    public string GetKeyFilePath() => _keyFilePath;

    /// <summary>
    /// 检查密钥是否来自环境变量
    /// </summary>
    public bool IsUsingEnvironmentVariable()
    {
        return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SUMER_ENCRYPTION_KEY"));
    }

    /// <summary>
    /// 轮换密钥（高级功能）
    /// 生成新密钥并返回，需要手动处理数据重新加密
    /// </summary>
    public string RotateKey()
    {
        _logger.LogWarning("🔄 开始密钥轮换操作");

        var oldKeyPath = _keyFilePath + ".old";

        // 备份旧密钥
        if (File.Exists(_keyFilePath))
        {
            File.Copy(_keyFilePath, oldKeyPath, true);
            _logger.LogInformation("旧密钥已备份到: {Path}", oldKeyPath);
        }

        // 生成新密钥
        var newKey = GenerateSecureKey();
        File.WriteAllText(_keyFilePath, newKey);

        if (!OperatingSystem.IsWindows())
        {
            File.SetUnixFileMode(_keyFilePath, UnixFileMode.UserRead | UnixFileMode.UserWrite);
        }

        _logger.LogInformation("✅ 新密钥已生成: {Path}", _keyFilePath);
        _logger.LogWarning("⚠️  需要使用新密钥重新加密所有敏感数据");

        return newKey;
    }
}
